package com.authine.cloudpivot.ext.applicationservice.api;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.Assert;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.applicationservice.CustomerOrderService;
import com.authine.cloudpivot.ext.applicationservice.base.ApplicationBaseService;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.ZookeeperLockConstants;
import com.authine.cloudpivot.ext.dto.*;
import com.authine.cloudpivot.ext.dto.api.BulkRefundVO;
import com.authine.cloudpivot.ext.dto.finance.TradeErpPoUpdate;
import com.authine.cloudpivot.ext.dto.system.UserDto;
import com.authine.cloudpivot.ext.enums.OrderGoodsStatusV1Enum;
import com.authine.cloudpivot.ext.enums.order.*;
import com.authine.cloudpivot.ext.eum.CustomerOrderStatusV1Enum;
import com.authine.cloudpivot.ext.model.order.CustomerOrderGoodsVo;
import com.authine.cloudpivot.ext.model.order.OrderTraceVO;
import com.authine.cloudpivot.ext.service.DockFinanceService;
import com.authine.cloudpivot.ext.service.OrderCustomerBaseV1Service;
import com.authine.cloudpivot.ext.service.OrderService;
import com.authine.cloudpivot.ext.service.OrderVendorBaseV1Service;
import com.authine.cloudpivot.ext.service.impl.DockFinanceServiceImpl;
import com.authine.cloudpivot.ext.service.impl.OrderCustomerBaseV1ServiceImpl;
import com.authine.cloudpivot.ext.service.impl.OrderServiceImpl;
import com.authine.cloudpivot.ext.service.impl.OrderVendorBaseV1ServiceImpl;
import com.authine.cloudpivot.ext.utils.*;
import com.authine.cloudpivot.ext.utils.logistics.LogisticsUtils;
import com.authine.cloudpivot.ext.utils.system.SessionUser;
import com.authine.cloudpivot.ext.utils.system.UserUtils;
import com.authine.cloudpivot.ext.vo.*;
import com.authine.cloudpivot.ext.vo.i.IOrderCustomerGoodsVO;
import com.authine.cloudpivot.ext.vo.i.IOrderCustomerVO;
import com.authine.cloudpivot.ext.vo.i.IOrderVendorVO;
import com.authine.hermes.lib.cloudpivot.cache.core.lock.MultiRetryLock;
import com.authine.mvp.app.launcher.domain.AttachmentFormat;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.utils.JsonParseObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.transaction.support.TransactionTemplate;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * 取消订单
 */
@Path("OrderCustomerV1Service")
@Slf4j
public class OrderCustomerV1Service extends ApplicationBaseService {
    private NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);
    private OrderService orderService = new OrderServiceImpl();
    private OrderCustomerBaseV1Service orderCustomerBaseV1Service = new OrderCustomerBaseV1ServiceImpl();
    private OrderVendorBaseV1Service orderVendorBaseV1Service = new OrderVendorBaseV1ServiceImpl();
    private DockFinanceService dockFinanceService = new DockFinanceServiceImpl();
    private TransactionTemplate transactionTemplate = ApplicationContextUtils.getBean(TransactionTemplate.class);

    /**
     * 客户查询接单信
     *
     * @return
     */
    @Path("customerGetAcceptwarn")
    @POST
    @Operation(summary = "对外接口-客户查询接单信息", tags = CUSTOM_SERVICE, description = "分页查询订单")
    public GatewayResponse customerGetAcceptwarn(@Parameter GatewayParam param) {
        log.warn("[customer-accept] begin:执行类：{},执行方法：getAcceptwarn（客户查询接单信）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
        String newOrderIds = StrUtil.utf8Str(body.get("newOrderIds"));
        List<String> orderIds = null == body.get("orderIds[]") ? null : (List<String>) body.get("orderIds[]");
        List orderIdList = new ArrayList();
        if (StringUtils.isNotBlank(newOrderIds)) {
            if (CollectionUtils.isNotEmpty(orderIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderIds = StringUtils.commaDelimitedTrimEmptyListString(newOrderIds);
            log.warn("使用过期参数 [customer-accept]-orderIds[] , {}", org.apache.commons.lang3.StringUtils.join(orderIds, ","));
            for (String orderId : orderIds) {
                Map<String, Object> result = selectModelById(orderId, ModelConst.T_ORDER_CUSTOMER);
                if (null == result || result.isEmpty()) {
                    return GatewayResponse.failed("订单id不存在");
                }

                String tableName = getTableName(ModelConst.T_ORDER_VENDOR);
                String ocTableName = getTableName(ModelConst.T_ORDER_CUSTOMER);
                StringBuilder getReceivingSql = new StringBuilder();

                getReceivingSql.append("select count(v.id) from " + tableName + " v where deleted ='0' and v.order_customer_id ='" + orderId + "' " +
                        "and v.order_vendor_status in ('" + OrderVendorStatusEnum.UpcomingPayment.name() + "','" + OrderVendorStatusEnum.UpcomingConfirm.name() + "')");
                log.info("------------------------ SQL：{}------------------------", getReceivingSql);
                Integer receivingCount = 0;
                try {
                    receivingCount = jdbcTemplate.queryForObject(getReceivingSql.toString(), new HashMap<>(), Integer.class);
                } catch (DataAccessException e) {
                    e.printStackTrace();
                }
                if (receivingCount > 0) {
                    orderIdList.add(orderId);
                }
            }
            if (orderIdList.size() <= 0) return GatewayResponse.success("未接单");
        }
        return GatewayResponse.success(orderIdList.size(), "供应商已接单", orderIdList);
    }

    @Path("customerOrderCancel")
    @POST
    @Operation(summary = "对外接口-客户取消订单", tags = CUSTOM_SERVICE, description = "客户取消订单")
    public GatewayResponse customerOrderCancel(@Parameter GatewayParam param) {
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
        //外部订单ID 多个id以,分隔
        String clientOrderId = (String) body.get("clientOrderId");
        //erpPo 多个erpPo以,分隔
        String erpPo = (String) body.get("erpPo");
        //订单ID 多个id以,分隔
        String customerOrderId = (String) body.get("orderCustomerId");

        log.warn("[customer-cancel] begin:执行类：{},执行方法：customerOrderCancel（客户取消订单）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> ocParam = new HashMap<>();
        List<String> erpPoList = null;
        if (RegexUtils.notNull(erpPo)) {
            erpPoList = Arrays.asList(org.apache.commons.lang3.StringUtils.split(erpPo, ","));
            //过滤值为空的数据
            erpPoList = erpPoList.stream().filter(Objects::nonNull).collect(Collectors.toList());
            ocParam.put("erp_po", erpPoList);
        }

        List<String> orderCustomerIdList = null;
        if (RegexUtils.notNull(customerOrderId)) {
            if (!RegexUtils.check(RegexUtils.Type.ONLY_NUMBER_OR_EMPTY, customerOrderId)) {
                return GatewayResponse.failed("参数不可为空或格式错误");
            }

            orderCustomerIdList = new ArrayList<>();
            for (String indexOrderCustomerId : org.apache.commons.lang3.StringUtils.split(customerOrderId, ",")) {
                orderCustomerIdList.add(indexOrderCustomerId);
            }
            //过滤值为空的数据
            orderCustomerIdList = orderCustomerIdList.stream().filter(Objects::nonNull).collect(Collectors.toList());
            ocParam.put("order_customer_id", orderCustomerIdList);
        }

        List<String> clientOrderIds = null;
        if (RegexUtils.notNull(clientOrderId)) {
            clientOrderIds = Arrays.asList(org.apache.commons.lang3.StringUtils.split(clientOrderId, ","));
            clientOrderIds = clientOrderIds.stream().filter(Objects::nonNull).collect(Collectors.toList());
            ocParam.put("client_order_id", clientOrderIds);
        }

        if (CollectionUtils.isEmpty(erpPoList) && CollectionUtils.isEmpty(orderCustomerIdList) && CollectionUtils.isEmpty(clientOrderIds)) {
            return GatewayResponse.failed("参数不能全部为空");
        }
        //根据参数获取客户订单ID
        List<Map<String, Object>> results = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*")
                .in("id", orderCustomerIdList).in("erp_po", erpPoList).in("client_order_id", clientOrderIds)
//                .eq("organization_id ->'$.id'", getSelectorFormat(null, UnitType.DEPARTMENT).getId())
                .queryForList();
        if (CollectionUtils.isEmpty(results)) {
            return GatewayResponse.failed("未获取到需要取消的订单，请检查erpPo或订单ID是否正确");
        }
        List<String> customerOrderIds = new ArrayList<>();
        for (Map<String, Object> orderCustomer : results) {
            OrderCustomerStatusEnum statusEnum = OrderCustomerStatusEnum.valueOf((String) orderCustomer.get("order_customer_status"));
            if (null != orderCustomer && (OrderCustomerStatusEnum.UpcomingPayment.des.equals(statusEnum.des) || OrderCustomerStatusEnum.UpcomingPayment.name().equals(statusEnum.name()))) {
                customerOrderIds.add((String) orderCustomer.get("id"));
            }
        }
        OrderCustomerDto oc = new OrderCustomerDto();
        oc.setIds(customerOrderIds);
        oc.setOrderCustomerStatus(OrderCustomerStatusEnum.Closed);
        SingleResponse response = orderService.batchUpdateOrderCustomer(oc);
        if (!response.isSuccess()) {
            log.error("[customer-cancel]订单取消异常，愿因：{}", response.getErrMessage());
            throw new RuntimeException("订单取消异常!");
        }
        return GatewayResponse.success(customerOrderIds.size(), "取消成功");
    }


    @Path("customerCreate")
    @POST
    @Operation(summary = "对外接口-客户创建订单", tags = CUSTOM_SERVICE, description = "客户创建订单")
    public GatewayResponse customerCreate(@Parameter GatewayParam param) {
        log.info("[customerCreate] begin:执行类：{},请求人：" + this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post", "orderGoodsVo");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
        IOrderCustomerVO customerOrder;
        String currentClientID = RequestContext.getClientId();
        String currentMemberID = RequestContext.getLoginId();
        //付款
        MultiRetryLock lock = null;
        boolean isLock = false;
        String lockString;
        CustomerOrderVo orderVo = new CustomerOrderVo();
        orderVo.setClient_user_id(Objects.toString(body.get("clientUserId"), ""));
        orderVo.setClient_order_id(Objects.toString(body.get("clientOrderId"), ""));
        orderVo.setReceiver(Objects.toString(body.get("receiver"), ""));
        orderVo.setPhone(Objects.toString(body.get("phone"), ""));
        orderVo.setAddress(Objects.toString(body.get("address"), ""));
        orderVo.setActual_order(Objects.toString(body.get("actualOrder"), ""));
        orderVo.setAmount(BigDecimalUtils.isNull(body.get("amount")));
        orderVo.setClientFactoryCode(Objects.toString(body.get("clientFactoryCode"), ""));
        orderVo.setClient_os(Objects.toString(body.get("clientOs"), ""));
        orderVo.setErp_po(Objects.toString(body.get("erpPO"), ""));
        orderVo.setExtends_attr(Objects.toString(body.get("extendsAttr"), ""));
        List<Map<String, Object>> orderGoodsList = (ArrayList) body.get("orderGoodsVo");
        List<CustomerOrderGoodsVo> customerOrderGoodsVos = new ArrayList<>();
        orderVo.setCustomerOrderGoodsVo(customerOrderGoodsVos);
        for (int i = 0; i < orderGoodsList.size(); i++) {
            if (null == orderGoodsList.get(i).get("src")) {
                return GatewayResponse.failed("商品来源类型不能为空");
            }
            CustomerOrderGoodsVo customerOrderGoodsVo = new CustomerOrderGoodsVo();
            customerOrderGoodsVo.setGoods_id(Objects.toString(orderGoodsList.get(i).get("goodsId"), ""));
            customerOrderGoodsVo.setGoods_src(Objects.toString(orderGoodsList.get(i).get("src"), ""));
            customerOrderGoodsVo.setClient_order_goods_id(Objects.toString(orderGoodsList.get(i).get("clientOrderGoodsId"), ""));
            customerOrderGoodsVo.setNum(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("num")));
            customerOrderGoodsVo.setAmount(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("amount")));
            customerOrderGoodsVo.setBrand(Objects.toString(orderGoodsList.get(i).get("brand"), ""));
            customerOrderGoodsVo.setCompany(Objects.toString(orderGoodsList.get(i).get("company"), ""));
            customerOrderGoodsVo.setDelivery(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("delivery")));
            customerOrderGoodsVo.setExtends_attr(Objects.toString(orderGoodsList.get(i).get("extendsAttr"), ""));
            customerOrderGoodsVo.setGolden_tax(Objects.toString(orderGoodsList.get(i).get("goldenTax"), ""));
            customerOrderGoodsVo.setMemo(Objects.toString(orderGoodsList.get(i).get("memo"), ""));
            customerOrderGoodsVo.setModel(Objects.toString(orderGoodsList.get(i).get("model"), ""));
            customerOrderGoodsVo.setName(Objects.toString(orderGoodsList.get(i).get("name"), ""));
            customerOrderGoodsVo.setPackage_num(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("packageNum")));
            customerOrderGoodsVo.setPackage_unit(Objects.toString(orderGoodsList.get(i).get("packageUnit"), ""));
            customerOrderGoodsVo.setPretax_freight(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("pretaxFreight")));
            customerOrderGoodsVo.setPretax_price(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("pretaxPrice")));
            customerOrderGoodsVo.setPrice(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("price")));
            customerOrderGoodsVo.setRegion(Objects.toString(orderGoodsList.get(i).get("region"), ""));
            customerOrderGoodsVo.setSku(Objects.toString(orderGoodsList.get(i).get("sku"), ""));
            customerOrderGoodsVo.setSpec(Objects.toString(orderGoodsList.get(i).get("spec"), ""));
            customerOrderGoodsVo.setTax_rate(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("taxRate")));
            customerOrderGoodsVo.setFreight_rate(BigDecimalUtils.integerToBigDecimal(orderGoodsList.get(i).get("taxRateFreight")));
            customerOrderGoodsVo.setUnit(Objects.toString(orderGoodsList.get(i).get("unit"), ""));
            customerOrderGoodsVo.setVendor_organization_id(UserUtils.getUserByUserId(Objects.toString(orderGoodsList.get(i).get("vendorId"))).createSelectorFormat());
            customerOrderGoodsVo.setWarehouse(Objects.toString(orderGoodsList.get(i).get("warehouse"), ""));
            customerOrderGoodsVos.add(customerOrderGoodsVo);
        }
        try {
            if (RegexUtils.notNull(orderVo.getClient_order_id())) {
                lockString = EncryptUtils.MD5_32(currentClientID + orderVo.getClient_order_id());
            } else {
                ObjectMapper objectMapper = new ObjectMapper();
                lockString = EncryptUtils.MD5_32(objectMapper.writeValueAsString(orderVo)) + currentMemberID;
            }
//            lock = zookeeperLockRegistry.obtain(lockString);
//            log.debug("v1订单创建开始加锁 {}", lockString);
//            isLock = lock.tryLock(30, TimeUnit.SECONDS);
            if (RegexUtils.notNull(orderVo.getClient_order_id())) {
                List<Map<String, Object>> customerOrders = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").eq("client_order_id", orderVo.getClient_order_id())
                        .eq("client_id", currentClientID).queryForList();
                if (customerOrders != null && !customerOrders.isEmpty()) {
                    return GatewayResponse.success("订单提交成功", customerOrders.stream().map(t -> t.get("client_order_id")).collect(Collectors.toList()).get(0));
                }
            }
//            if (!isLock) {
//                return GatewayResponse.success("业务数据已在提交中，请勿重复提交！");
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        customerOrder = orderService.iCreateOrder(orderVo);

        //TODO 异步调用晶科请购单完成方法
//      iOrdersService.completePurchaseRequest(customerOrder);
        return GatewayResponse.success(1, "订单创建成功", getCustomerOrderMap(customerOrder));
    }

    private Map<String, Object> getCustomerOrderMap(IOrderCustomerVO customerOrder) {
        log.warn("[biz-group] begin:执行类：{},执行方法：getCustomerOrderMap（客户订单Map）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        List<Map> igResult = new ArrayList<>();
        for (IOrderVendorVO v : customerOrder.getOrderVendorVO()) {
            for (IOrderCustomerGoodsVO o : v.getOrderCustomerGoodsVO()) {
                Map<String, Object> map = new HashMap<>();
                map.put("clientOrderGoodsId", o.getClient_order_goods_id());
                map.put("orderGoodsId", o.getId());
                igResult.add(map);
            }
        }
        Map<String, Object> map1 = new HashMap<>();
        map1.put("clientOrderId", customerOrder.getClient_order_id());
        map1.put("orderId", customerOrder.getId());
        map1.put("orderGoods", igResult);
        log.warn("[biz-group] end:执行类：{},执行方法：getCustomerOrderMap（客户订单Map）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        return map1;
    }

    @Path("customerGoodsDelivery")
    @POST
    @Operation(summary = "对外接口-查询物流信息(getDeliveywarn)", tags = CUSTOM_SERVICE, description = "查询物流信息")
    public GatewayResponse customerGoodsDelivery(@Parameter GatewayParam param) throws Exception {
        log.info("[customerGoodsDelivery] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
        //订单商品id集合(逗号分隔)
        String newOrderGoodsIds = (String) body.get("newOrderGoodsIds");

        List<String> orderGoodsIds = (List<String>) body.get("orderGoodsIds[]");

        if (org.apache.commons.lang3.StringUtils.isNotBlank(newOrderGoodsIds)) {
            if (CollectionUtils.isNotEmpty(orderGoodsIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderGoodsIds = StringUtils.commaDelimitedTrimEmptyListString(newOrderGoodsIds);
        } else {
            log.warn("使用过期参数 [goods-delivery]-orderGoodsIds[] , {}", org.apache.commons.lang3.StringUtils.join(orderGoodsIds, ","));
        }

        if (null == orderGoodsIds || orderGoodsIds.isEmpty()) {
            return GatewayResponse.failed("参数不正确");
        }
        String requestId = UUID.randomUUID().toString();
        try {
            // 加锁
            Boolean aBoolean = RedisLockUtil.lock(EncryptUtils.MD5_32(ZookeeperLockConstants.CUSTOMER_DELIVERY_V1 + orderGoodsIds), 300, 3, requestId);
            Assert.isTrue(aBoolean, "请勿重复提交! ");
            // 根据订单商品id列表获取物流信息
            Map<String, Object> data = new HashMap<>();
            String traceTable = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_TRACE);
            String orderCustomerGoodsTable = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
            String orderGoodsRelationTable = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_GOODS_RELATION);

            StringBuilder st = new StringBuilder(" SELECT trace.id, trace.order_customer_goods_id, trace.waybill, trace.logistics, trace.quantity, trace.createdTime, goods.`name`, goods.sku, relation.company, goods.price, goods.amount  FROM  ");
            st.append(traceTable);
            st.append(" trace LEFT JOIN ");
            st.append(orderCustomerGoodsTable);
            st.append(" goods ON goods.id = trace.order_customer_goods_id  LEFT JOIN ");
            st.append(orderGoodsRelationTable);
            st.append(" relation ON relation.id = goods.relation_id WHERE trace.order_customer_goods_id IN ( :orderCustomerGoodIds ) ");

            data.put("orderCustomerGoodIds", orderGoodsIds);
            List<Map<String, Object>> mapList = JdbcTemplateUtils.queryForList(st.toString(), data);

            if (CollectionUtils.isEmpty(mapList)) {
                return GatewayResponse.success();
            }

            List<OrderTraceVO> orderTraceVOS = OrderTraceVO.transferToOrderTraceVOList(mapList);
            log.info("[customerGoodsDelivery] end  >>>>>>>");
            return GatewayResponse.success(orderTraceVOS.size(), "查询成功", orderTraceVOS);

        } finally {
            Boolean aBoolean = RedisLockUtil.unlock(EncryptUtils.MD5_32(ZookeeperLockConstants.CUSTOMER_DELIVERY_V1 + orderGoodsIds), requestId);
            if (!aBoolean) {
                log.warn("【customerGoodsDelivery】 解锁失败 key：{}", ZookeeperLockConstants.CUSTOMER_DELIVERY_V1 + orderGoodsIds);
            }
        }

    }

    @Path("customerById")
    @POST
    @Operation(summary = "对外接口-根据订单id查询客户订单(customerById)", tags = CUSTOM_SERVICE, description = "根据订单id查询客户订单")
    public GatewayResponse customerById(@Parameter GatewayParam param) {
        log.info("[customerById] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get", "id");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
        //供应商订单id
        String id = (String) body.get("id");
//        Assert.isTrue(StringUtils.isNotBlank(id), "请求参数查询条件id 不能为空");

        //涉及用户权限问题
        UserDto currentUser = UserUtils.getCurrentUser();
        Assert.notNull(currentUser, "当前登录用户 不能为空");

        List<String> memberIds = UserUtils.listSubMemberIds(currentUser.getId());

        Map<String, Object> orderCustomer = new HashMap<>();
        //客户订单id
        if (CollectionUtils.isEmpty(memberIds)) {
            //如果返回为空，就表示当前用户 具有所有数据查看权限 直接根据id查询出来数据
            orderCustomer = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").eq("id", id).queryForMap();
        } else {
            //有数据需要过滤
            orderCustomer = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").eq("id", id).in("JSON_UNQUOTE(place_order_user_id ->'$.id')", memberIds).queryForMap();
        }

        Assert.notNull(orderCustomer, "查询客户订单信息 不能为空");

        CustomerOrderV1VO customerOrderV1VO = CustomerOrderV1VO.of().setOrderId(String.valueOf(orderCustomer.get("id")))
                .setClientOrderId(String.valueOf(orderCustomer.get("client_order_id")))
                .setStatus(String.valueOf(orderCustomer.get("order_customer_status")))
                .setErpPO(String.valueOf(orderCustomer.get("erp_po")))
                .setReceiver(String.valueOf(orderCustomer.get("receiver")))
                .setPhone(String.valueOf(orderCustomer.get("phone")))
                .setPostal(String.valueOf(orderCustomer.get("postal")))
                .setAddress(String.valueOf(orderCustomer.get("address")))
                .setTotal(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("total")))
                .setFreight(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("freight")))
                .setPretaxAmount(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("pretax_amount")))
                .setAmount(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("amount")))
                .setMemberName(String.valueOf(orderCustomer.get("place_order_fullname")))
                .setTime(Utils.strToDate(String.valueOf(orderCustomer.get("createdTime"))))
                .setApprovalBy(String.valueOf(orderCustomer.get("approval_by")))
                .setApprovalOpinion(String.valueOf(orderCustomer.get("approval_opinion")))
                .setCustomerName(String.valueOf(orderCustomer.get("organization_name")));

        //获取 对应的供应商订单
        List<Map<String, Object>> vendorOrderList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).selectField("*").eq("order_customer_id", id).queryForList();

        Assert.isTrue(CollectionUtils.isNotEmpty(vendorOrderList), "查询供应商订单信息 不能为空");

        //需要判断当前用户是否是平台用户 权限过滤数据使用
        List<Map<String, Object>> vendorOrderGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).selectField("*").eq("order_customer_id", id).queryForList();

        Assert.isTrue(CollectionUtils.isNotEmpty(vendorOrderGoodsList), "查询供应商订单商品信息 不能为空");

        List<String> relationIdList = vendorOrderGoodsList.stream().map(e -> String.valueOf(e.get("relation_id"))).collect(Collectors.toList());

        List<Map<String, Object>> goodsRelationList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RELATION).selectField("*").in("id", relationIdList).queryForList();

        Assert.isTrue(CollectionUtils.isNotEmpty(goodsRelationList), "查询供应商订单商品关系信息 不能为空");
        Map<String, Map<String, Object>> relationMap = null;
        if (!CollectionUtils.isEmpty(goodsRelationList)) {
            relationMap = goodsRelationList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

        }
        Map<String, Map<String, Object>> vendorOderMap = vendorOrderList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

        List<OrderGoodsV1VO> orderGoodsV1VOList = new LinkedList<>();
        for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {

            Map<String, Object> relation = null == relationMap ? null : relationMap.getOrDefault(String.valueOf(vendorOrderGoods.get("relation_id")), null);
            Map<String, Object> vendorOder = vendorOderMap.getOrDefault(String.valueOf(vendorOrderGoods.get("order_vendor_id")), null);

            int attachmentSize = 0;
            if (vendorOrderGoods.get("attachment") != null) {
                List<AttachmentFormat> attachment = JsonParseObject.parseObject(String.valueOf(vendorOrderGoods.get("attachment")), AttachmentFormat.class);
                attachmentSize = attachment.size();
            }

            Map<String, Object> inquiry = null;
            if (null != relation) {
                //询价
                String inquiryId = String.valueOf(relation.get("inquiry_id"));
                inquiry = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY).selectField("*").eq("id", inquiryId).queryForMap();
            }

            //报价
            Map<String, Object> quotationGoods = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS).selectField("*").eq("id", vendorOrderGoods.get("goods_id")).queryForMap();

            OrderGoodsV1VO orderGoodsV1VO = OrderGoodsV1VO.of().setOrderGoodsId(String.valueOf(vendorOrderGoods.get("id")))
                    .setClientOrderGoodsId(String.valueOf(vendorOrderGoods.get("client_order_goods_id")))
                    .setCustomerOrderId(String.valueOf(vendorOrderGoods.get("order_customer_id")))
                    .setVendorOrderId(String.valueOf(vendorOrderGoods.get("order_vendor_id")))
                    .setVendorName(String.valueOf(vendorOrderGoods.get("vendor_organization_name")))
                    .setName(String.valueOf(vendorOrderGoods.get("name")))
                    .setBrand(String.valueOf(vendorOrderGoods.get("brand")))
                    .setModel(String.valueOf(vendorOrderGoods.get("model")))
                    .setSpec(String.valueOf(vendorOrderGoods.get("spec")))
                    .setSku(String.valueOf(vendorOrderGoods.get("sku")))
                    .setBarCode(String.valueOf(vendorOrderGoods.get("bar_code")))
                    .setUnspsc(String.valueOf(vendorOrderGoods.get("unspsc")))
                    .setGoldenTax(String.valueOf(vendorOrderGoods.get("golden_tax")))
                    .setImages(String.valueOf(vendorOrderGoods.get("images")))
                    .setDescription(String.valueOf(vendorOrderGoods.get("description")))
                    .setTechnical(String.valueOf(vendorOrderGoods.get("technical")))
                    .setPackaging(String.valueOf(vendorOrderGoods.get("packaging")))
                    .setMemo(String.valueOf(vendorOrderGoods.get("memo")))
                    .setUnit(String.valueOf(vendorOrderGoods.get("unit")))
                    .setPackageUnit(String.valueOf(vendorOrderGoods.get("package_unit")))
                    .setNum(null == vendorOrderGoods.get("quantity") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("quantity")))
                    .setPackageNum(null == vendorOrderGoods.get("package_quantity") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("package_quantity")))
                    .setDelivery(null == vendorOrderGoods.get("delivery") ? null : BigDecimalUtils.bigDecimalToInteger(vendorOrderGoods.get("delivery")))
                    .setTaxRate(null == vendorOrderGoods.get("tax_rate") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("tax_rate")))
                    .setTaxRateFreight(null == vendorOrderGoods.get("freight_rate") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("freight_rate")))
                    .setPretaxPrice(null == vendorOrderGoods.get("pretax_price") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_price")))
                    .setPrice(null == vendorOrderGoods.get("price") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("price")))
                    .setPretaxFreight(null == vendorOrderGoods.get("pretax_freight") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_freight")))
                    .setFreight(null == vendorOrderGoods.get("freight") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("freight")))
                    .setPretaxTotal(null == vendorOrderGoods.get("pretax_total") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_total")))
                    .setTotal(null == vendorOrderGoods.get("total") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("total")))
                    .setPretaxAmount(null == vendorOrderGoods.get("pretax_amount") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_amount")))
                    .setAmount(null == vendorOrderGoods.get("amount") ? null : BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("amount")))
                    .setStatus(String.valueOf(vendorOrderGoods.get("order_vendor_goods_status")))
                    .setAttachment(String.valueOf(attachmentSize))
                    .setOrderType(String.valueOf(orderCustomer.get("type")))
                    .setCustomerOrgName(String.valueOf(vendorOrderGoods.get("customer_organization_name")))
                    .setMemberName(String.valueOf(orderCustomer.get("place_order_fullname"))) //实际下单人？
                    .setTime(Utils.strToDate(String.valueOf(vendorOder.get("createdTime"))))
                    .setClarifyTips(quotationGoods == null ? null : String.valueOf(quotationGoods.get("clarify_tips")))
                    .setCategory(String.valueOf(vendorOrderGoods.get("category")))
                    .setRemarkMessages(quotationGoods == null ? null : String.valueOf(quotationGoods.get("remark_message")))
                    .setQuotationGoodsId(String.valueOf(vendorOrderGoods.get("goods_id")))
                    .setDemandDeptName(inquiry == null ? null : String.valueOf(inquiry.get("department_name")))
                    .setInquiryMemberName(inquiry == null ? null : String.valueOf(inquiry.get("member_name")));

            orderGoodsV1VOList.add(orderGoodsV1VO);
        }

        customerOrderV1VO.setOrderGoods(orderGoodsV1VOList);
        log.info("[customerById] end  >>>>>>>");
        return GatewayResponse.success(1, "查询成功", customerOrderV1VO);
    }


    @Path("customerLogisticsDetail")
    @POST
    @Operation(summary = "对外接口-根据物流单号查询物流详情(getLogisticsDetail)", tags = CUSTOM_SERVICE, description = "根据物流单号查询物流详情")
    public GatewayResponse customerLogisticsDetail(@Parameter GatewayParam param) {
        log.info("[customerLogisticsDetail] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get", "waybills");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
        // 物流单号
        String waybills = (String) body.get("waybills");

        List<JSONObject> logicDetailJsonData = new ArrayList();
        for (String waybill : waybills.replace(" ", "").split("/")) {
            ApiLogisticsInfo apiLogisticsInfo = ApiLogisticsInfo.builder().build();
            String logCode = "";
            //获取 订单号对应的 物流公司
            JSONObject logCodeResult = LogisticsUtils.getLogCode(waybill);
            if (null != logCodeResult && null != logCodeResult.get("showapi_res_body") &&
                    !CollectionUtils.isEmpty(logCodeResult.getJSONObject("showapi_res_body").getJSONArray("data"))) {

                JSONArray jsonArray = logCodeResult.getJSONObject("showapi_res_body").getJSONArray("data");
                logCode = jsonArray.getJSONObject(0).getString("simpleName");
            }

            JSONObject logisticsDetail = (JSONObject) LogisticsUtils.queryLogistics(logCode, waybill, null);
            logicDetailJsonData.add(logisticsDetail);
        }
        List<ApiLogisticsInfo> results = ApiLogisticsInfo.getListBylogicDetail(logicDetailJsonData);
        log.info("[customerLogisticsDetail] end  >>>>>>>");
        return GatewayResponse.success(results == null ? 0 : results.size(), results);
    }


    @Path("customerLogisticsList")
    @POST
    @Operation(summary = "对外接口-根据客户订单ID查询物流单(getLogisticsList)", tags = CUSTOM_SERVICE, description = "根据客户订单ID查询物流单")
    public GatewayResponse customerLogisticsList(@Parameter GatewayParam param) {
        log.info("[customerLogisticsList] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get", "orderCustomerIds");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");
        // 物流单号
        String orderCustomerIds = (String) body.get("orderCustomerIds");
//        Assert.isTrue(StringUtils.isNotBlank(orderCustomerIds), "请求参数查询条件id 不能为空");

        if (!RegexUtils.check(RegexUtils.Type.ONLY_NUMBER_OR_EMPTY, orderCustomerIds)) {
            return GatewayResponse.failed("参数不能为空或格式有误");
        }

        List<String> orderCustomerIdList = Arrays.asList(org.apache.commons.lang3.StringUtils.split(orderCustomerIds, ","));
        String requestId = UUID.randomUUID().toString();

        try {
            // 加锁
            Boolean aBoolean = RedisLockUtil.lock(EncryptUtils.MD5_32(ZookeeperLockConstants.LOGISTICS_INFO_V1 + orderCustomerIdList), 300, 3, requestId);
            Assert.isTrue(aBoolean, "请勿重复提交! ");

            String orderCustomerGoodsT = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
            String orderCustomerT = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_CUSTOMER);
            String orderVendorT = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_VENDOR);

            StringBuilder sp = new StringBuilder("SELECT d.id FROM  ( SELECT o.id, o.order_customer_id FROM ");
            sp.append(orderCustomerGoodsT);
            sp.append(" o LEFT JOIN ");
            sp.append(orderVendorT);
            sp.append(" v ON o.order_vendor_id = v.id ) d  LEFT JOIN ");
            sp.append(orderCustomerT);
            sp.append(" c ON d.order_customer_id = c.id WHERE c.id IN (:orderCustomerIdList) ");

            Map<String, Object> queryParam = new HashMap<>();
            queryParam.put("orderCustomerIdList", orderCustomerIdList);
            List<Map<String, Object>> mapList = JdbcTemplateUtils.queryForList(sp.toString(), queryParam);

            List<String> orderCustomerGoodsIds = new ArrayList<>();

            if (!CollectionUtils.isEmpty(mapList)) {
                mapList.stream().forEach(e -> {
                    orderCustomerGoodsIds.add(String.valueOf(e.get("id")));
                });
            }

            List<TransportVo> transportVos = new ArrayList<>();

            if (!CollectionUtils.isEmpty(orderCustomerGoodsIds)) {

                String orderTraceT = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_TRACE);
                String orderGoodsRelationT = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_GOODS_RELATION);

                StringBuilder st = new StringBuilder(" SELECT transport.id, transport.order_customer_goods_id,transport.waybill,transport.logistics, transport.quantity, transport.createdTime,goods.NAME,  goods.sku,  relation.company,goods.price, goods.amount  FROM ");
                st.append(orderTraceT);
                st.append(" transport LEFT JOIN ");
                st.append(orderCustomerGoodsT);
                st.append(" goods ON goods.id = transport.order_customer_goods_id  LEFT JOIN ");
                st.append(orderGoodsRelationT);
                st.append(" relation ON goods.relation_id = relation.id WHERE transport.order_customer_goods_id IN (:orderCustomerGoodsIds) ");

                Map<String, Object> queryParam2 = new HashMap<>();
                queryParam2.put("orderCustomerGoodsIds", orderCustomerGoodsIds);

                List<Map<String, Object>> queryList = JdbcTemplateUtils.queryForList(st.toString(), queryParam2);

                if (!CollectionUtils.isEmpty(queryList)) {
                    queryList.stream().forEach(e -> {
                        TransportVo transportVo = new TransportVo();

                        transportVo.setId(String.valueOf(e.get("id")));
                        transportVo.setOrderGoodsId(String.valueOf(e.get("order_customer_goods_id")));
                        transportVo.setWaybill(String.valueOf(e.get("waybill")));
                        transportVo.setLogistics(String.valueOf(e.get("logistics")));
                        transportVo.setNum(null == e.get("quantity") ? null : BigDecimalUtils.integerToBigDecimal(e.get("quantity")));
                        transportVo.setTime(Utils.strToDate(String.valueOf(e.get("createdTime"))));
                        transportVo.setName(String.valueOf(e.get("NAME")));
                        transportVo.setSku(String.valueOf(e.get("sku")));
                        transportVo.setCompany(String.valueOf(e.get("company")));
                        transportVo.setPrice(null == e.get("price") ? null : BigDecimalUtils.integerToBigDecimal(e.get("price")));
                        transportVo.setAmount(null == e.get("amount") ? null : BigDecimalUtils.integerToBigDecimal(e.get("amount")));

                        transportVos.add(transportVo);
                    });
                }
            }

            log.info("[customerLogisticsList] end  >>>>>>>");
            return GatewayResponse.success(transportVos.size(), "", transportVos);

        } finally {
            Boolean aBoolean = RedisLockUtil.unlock(EncryptUtils.MD5_32(ZookeeperLockConstants.LOGISTICS_INFO_V1 + orderCustomerIdList), requestId);
            if (!aBoolean) {
                log.warn("【customerLogisticsList】 解锁失败 key：{}", ZookeeperLockConstants.LOGISTICS_INFO_V1 + orderCustomerIdList);
            }
        }

    }

    @Path("deliveryRecordList")
    @POST
    @Operation(summary = "对外接口-供应商查询订单商品发货记录(deliveryRecord)", tags = CUSTOM_SERVICE, description = "供应商查询订单商品发货记录")
    public GatewayResponse deliveryRecordList(@Parameter GatewayParam param) {
        log.info("[deliveryRecordList] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get", "orderGoodsId");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");

        // 订单商品Id
        String orderGoodsId = (String) body.get("orderGoodsId");
//        Assert.isTrue(StringUtils.isNotBlank(orderGoodsId), "请求参数查询条件 orderGoodsId 不能为空");

        UserDto currentUser = UserUtils.getCurrentUser();
        Assert.notNull(currentUser, "当前登录用户 不能为空");
        //注意：如果返回为空，就表示当前用户 具有所有数据查看权限 直接根据id查询出来数据
        List<String> memberIds = UserUtils.listSubMemberIds(currentUser.getId());

        String orderTraceT = JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_TRACE);

        StringBuilder st = new StringBuilder(" SELECT trace.* FROM ");
        st.append(orderTraceT);

        st.append(" trace WHERE trace.order_vendor_goods_id = :orderGoodsId ");
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("orderGoodsId", orderGoodsId);

        //客户订单id
        if (!CollectionUtils.isEmpty(memberIds)) {
            //有数据需要过滤
            st.append(" AND JSON_UNQUOTE(trace.sender_id ->'$.id') IN (:memberIds) ");
            queryParam.put("memberIds", memberIds);
        }

        //查询的物流信息集合
        List<Map<String, Object>> traceList = JdbcTemplateUtils.queryForList(st.toString(), queryParam);

        if (CollectionUtils.isEmpty(traceList)) {
            return GatewayResponse.failed("未查到此订单商品的物流信息！");
        }

        List<TransportV1VO> transportV1VOList = new ArrayList<>();
        for (Map<String, Object> trace : traceList) {

            String recipientId = null;
            String senderId = null;
            if (null != trace.get("recipient_id")) {
                List<SelectorFormat> selectorFormats1 = JsonParseObject.parseObject(String.valueOf(trace.get("recipient_id")), SelectorFormat.class);
                recipientId = selectorFormats1.get(0).getId();
            }
            if (null != trace.get("sender_id")) {
                List<SelectorFormat> selectorFormats1 = JsonParseObject.parseObject(String.valueOf(trace.get("sender_id")), SelectorFormat.class);
                senderId = selectorFormats1.get(0).getId();
            }

            TransportV1VO transportV1VO = new TransportV1VO(TraceTypeEnum.valueOf(String.valueOf(trace.get("type"))).id, null, orderGoodsId,
                    recipientId, senderId, String.valueOf(trace.get("logistics")),
                    null == trace.get("quantity") ? null : BigDecimalUtils.integerToBigDecimal(trace.get("quantity")),
                    String.valueOf(trace.get("waybill")),
                    String.valueOf(trace.get("customer_organization_name")));

            Map<String, Object> vendorOrderGoods = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).selectField("*").eq("id", trace.get("order_vendor_goods_id")).queryForMap();

            if (null != vendorOrderGoods) {

                //拿到对应的供应商订单
                Map<String, Object> vendorOrder = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).selectField("*").eq("id", vendorOrderGoods.get("order_vendor_id")).queryForMap();
                Assert.notNull(vendorOrder, "查询供应商订单 为空");

                //获取客户订单数据
                Map<String, Object> customerOrder = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").eq("id", vendorOrder.get("order_customer_id")).queryForMap();
                Assert.notNull(customerOrder, "查询客户订单 为空");

                String goodsPurchaseT = JdbcTemplateUtils.getTableName(ModelConst.T_GOODS_PURCHASE, AppConst.COMMODITYMATERIALS);
                String quotationGoodsT = JdbcTemplateUtils.getTableName(ModelConst.T_QUOTATION_GOODS, AppConst.SOURCING_CENTER);
                StringBuilder quotationGoodsSql = new StringBuilder(" SELECT quotationGoods.* FROM ");
                quotationGoodsSql.append(goodsPurchaseT);
                quotationGoodsSql.append(" goodsPurchase LEFT JOIN ");
                quotationGoodsSql.append(quotationGoodsT);
                quotationGoodsSql.append(" quotationGoods ON goodsPurchase.quotation_goods_id = quotationGoods.id ");
                quotationGoodsSql.append(" WHERE goodsPurchase.id = :goods_id ");
                Map<String, Object> quotationGoodsQueryParam = new HashMap<>();
                quotationGoodsQueryParam.put("goods_id", vendorOrderGoods.get("goods_id"));
                //报价商品信息
                List<Map<String, Object>> quotationGoodList = JdbcTemplateUtils.queryForList(quotationGoodsSql.toString(), quotationGoodsQueryParam);
                Assert.notEmpty(quotationGoodList, "查询报价商品 为空");
                Map<String, Object> quotationGoods = quotationGoodList.get(0);
//                Map<String, Object> quotationGoods = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS).selectField("*").eq("id", vendorOrderGoods.get("goods_id")).queryForMap();
                Assert.notNull(quotationGoods, "查询报价商品 为空");

                String vendorOrganizationId = null;
                String placeOrderUserId = null;
                String modifiedBy = null;
                if (null != vendorOrderGoods.get("vendor_organization_id")) {
                    List<SelectorFormat> selectorFormats1 = JsonParseObject.parseObject(String.valueOf(vendorOrderGoods.get("vendor_organization_id")), SelectorFormat.class);
                    vendorOrganizationId = selectorFormats1.get(0).getId();
                }

                if (null != customerOrder.get("place_order_user_id")) {
                    List<SelectorFormat> selectorFormats2 = JsonParseObject.parseObject(String.valueOf(customerOrder.get("place_order_user_id")), SelectorFormat.class);
                    placeOrderUserId = selectorFormats2.get(0).getId();
                }

                if (null != vendorOrderGoods.get("modifiedBy")) {
//                    List<SelectorFormat> selectorFormats3 = JsonParseObject.parseObject(String.valueOf(vendorOrderGoods.get("modifiedBy")), SelectorFormat.class);
//                    modifiedBy = selectorFormats3.get(0).getId();
                    modifiedBy = (String) vendorOrderGoods.get("modifiedBy");
                }

                //todo username 这个字段目前没有，当前登录用户 登录名称 String.valueOf(vendorOrder.get("username")
                V2OrderGoodsPutVO v2OrderGoodsPutVO = new V2OrderGoodsPutVO(String.valueOf(vendorOrderGoods.get("id")),
                        String.valueOf(vendorOrderGoods.get("goods_src")), String.valueOf(vendorOrderGoods.get("client_order_goods_id")),
                        vendorOrganizationId, String.valueOf(vendorOrderGoods.get("name")),
                        String.valueOf(vendorOrderGoods.get("brand")), String.valueOf(vendorOrderGoods.get("model")),
                        String.valueOf(vendorOrderGoods.get("spec")), BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("quantity")),
                        String.valueOf(vendorOrderGoods.get("unit")), BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("package_quantity")),
                        String.valueOf(vendorOrderGoods.get("package_unit")), BigDecimalUtils.bigDecimalToInteger(vendorOrderGoods.get("delivery")),
                        String.valueOf(vendorOrderGoods.get("golden_tax")), BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("tax_rate")),
                        BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("freight_rate")), BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_price")),
                        BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("price")), BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_freight")),
                        BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("amount")), String.valueOf(vendorOrderGoods.get("memo")),
                        String.valueOf(vendorOrderGoods.get("order_vendor_goods_status")),
                        String.valueOf(customerOrder.get("place_order_fullname")), modifiedBy,
                        placeOrderUserId, String.valueOf(customerOrder.get("order_customer_status")),
                        String.valueOf(vendorOrder.get("order_vendor_status")), "username",
                        String.valueOf(customerOrder.get("receiver")), String.valueOf(customerOrder.get("phone")),
                        String.valueOf(customerOrder.get("postal")), String.valueOf(customerOrder.get("address")),
                        String.valueOf(vendorOrder.get("organization_name")), Utils.strToDate(String.valueOf(customerOrder.get("createdTime"))),
                        String.valueOf(customerOrder.get("id")), String.valueOf(vendorOrder.get("id")), String.valueOf(vendorOrderGoods.get("erp_po")),
                        BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_total")), BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("total")),
                        BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("total")), BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_amount")),
                        String.valueOf(vendorOrderGoods.get("attachment")), String.valueOf(customerOrder.get("type")),
                        String.valueOf(vendorOrderGoods.get("category")), null, null,
                        String.valueOf(quotationGoods.get("remark_message")), String.valueOf(vendorOrderGoods.get("goods_id")), null);


                transportV1VO.setOrderGoods(v2OrderGoodsPutVO);
            }

            transportV1VOList.add(transportV1VO);
        }

        log.info("[deliveryRecordList] end  >>>>>>>");

        return GatewayResponse.success("查询成功", transportV1VOList);
    }

    @Path("refundRecordList")
    @POST
    @Operation(summary = "对外接口-供应商查看退款记录(listRefundRecord)", tags = CUSTOM_SERVICE, description = "供应商查看退款记录")
    public GatewayResponse refundRecordList(@Parameter GatewayParam param) {
        log.info("[refundRecordList] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get", "orderGoodsId");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");

        // 订单商品Id
        String orderGoodsId = (String) body.get("orderGoodsId");
//        Assert.isTrue(StringUtils.isNotBlank(orderGoodsId), "请求参数查询条件 orderGoodsId 不能为空");

        UserDto currentUser = UserUtils.getCurrentUser();
        Assert.notNull(currentUser, "当前登录用户 不能为空");

        List<SelectorFormat> organization = currentUser.getOrganization_id();

        Map<String, Object> vendorOrderGoods = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).selectField("*")
                .eq("id", orderGoodsId).eq("vendor_organization_id -> '$.id'", organization.get(0).getId()).queryForMap();

        if (null == vendorOrderGoods) {
            return GatewayResponse.failed("订单商品" + orderGoodsId + "不存在, 请检查!");
        }

        //查询退货记录数据
        List<Map<String, Object>> orderGoodsReturnList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RETURNS).selectField("*").eq("order_vendor_goods_id", orderGoodsId).queryForList();

        if (CollectionUtils.isEmpty(orderGoodsReturnList)) {
            return GatewayResponse.failed("订单商品" + orderGoodsId + "不存在, 请检查!");
        }

        List<OrderGoodsRefundLogV1VO> orderGoodsRefundLogV1VOList = new ArrayList<>();
        for (Map<String, Object> orderGoodsReturn : orderGoodsReturnList) {
            if (null == orderGoodsReturn.get("extends_attr")) {
                continue;
            }
            JSONObject extendsAttr = JSONObject.parseObject(String.valueOf(orderGoodsReturn.get("extends_attr")));
            JSONArray logList = extendsAttr.getJSONArray("logs");
            for (int i = 0; i < logList.size(); i++) {
                Map<String, Object> log = logList.getJSONObject(i);
                OrderGoodsRefundLogV1VO orderGoodsRefundLogV1VO = new OrderGoodsRefundLogV1VO(StrUtil.utf8Str(log.get("operatorUserId")),
                        StrUtil.utf8Str(log.get("operator")), StrUtil.utf8Str(log.get("memo")), StrUtil.utf8Str(log.get("architectureName")),
                        String.valueOf(orderGoodsReturn.get("name")), StrUtil.utf8Str(log.get("behavior")));
                orderGoodsRefundLogV1VOList.add(orderGoodsRefundLogV1VO);
            }
        }

        log.info("[refundRecordList] end  >>>>>>>");
        return GatewayResponse.success("查询成功", orderGoodsRefundLogV1VOList);
    }

    @Path("customerGoodsPage")
    @POST
    @Operation(summary = "对外接口-客户分页查询订单商品", tags = CUSTOM_SERVICE, description = "客户分页查询订单商品")
    public GatewayResponse customerGoodsPage(@Parameter GatewayParam param) {
        log.info("[customerGoodsPage] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get", "page", "limit");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");
        SessionUser sessionUser = new SessionUser();
        if (null == sessionUser.get()) throw new BizException("未获取到登录信息!");
        //订单商品id集合(逗号分隔)
        String newOrderGoodsIds = (String) body.get("newOrderGoodsIds");
        //客户订单id集合(逗号分隔)
        String newCustomerOrderIds = (String) body.get("newCustomerOrderIds");
        //供应商订单id集合(逗号分隔)
        String newVendorOrderIds = (String) body.get("newVendorOrderIds");

        List<String> orderGoodsIds = (List<String>) body.get("orderGoodsIds[]");
        List<String> customerOrderIds = (List<String>) body.get("customerOrderIds[]");
        List<String> vendorOrderIds = (List<String>) body.get("vendorOrderIds[]");

        if (org.apache.commons.lang3.StringUtils.isNotBlank(newOrderGoodsIds)) {
            if (CollectionUtils.isNotEmpty(orderGoodsIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderGoodsIds = StringUtils.commaDelimitedTrimEmptyListString(newOrderGoodsIds);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(newCustomerOrderIds)) {
            if (CollectionUtils.isNotEmpty(customerOrderIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            customerOrderIds = StringUtils.commaDelimitedTrimEmptyListString(newCustomerOrderIds);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(newVendorOrderIds)) {
            if (CollectionUtils.isNotEmpty(vendorOrderIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            vendorOrderIds = StringUtils.commaDelimitedTrimEmptyListString(newVendorOrderIds);
        }

        //订单商品状态码, 0: 全部 1: 新建 2:待付款 3: 待发货 4:出库中 5:已发货 6:待退货 7:退货中 8:退款中 9:已退货 11:已完成 12:已关闭 13:退款申请中 14:已退款
        Integer statusCode = BigDecimalUtils.bigDecimalToInteger(body.get("statusCode"));
        //商品名称
        String brand = (String) body.get("brand");
        //品牌
        String name = (String) body.get("name");
        //型号
        String model = (String) body.get("model");
        //规格
        String spec = (String) body.get("spec");
        //当前第几页（默认1）
        Integer page = BigDecimalUtils.bigDecimalToInteger(body.get("page"));
        //每页条目数（limit<=100,默认20）
        Integer limit = BigDecimalUtils.bigDecimalToInteger(body.get("limit"));

        List<OrderGoodsV1VO> orderGoodsV1VOList = new ArrayList<>();
        Integer count = null;

        //todo 根据 是客户（客户订单商品） 还是 供应商（供应商订单商品）
        if (sessionUser.isCustomer()) {
            //查询 客户订单商品
            OrderCustomerGoodsDto orderCustomerGoodsDto = new OrderCustomerGoodsDto();
            orderCustomerGoodsDto.setIds(orderGoodsIds);
            orderCustomerGoodsDto.setOrderCustomerIds(customerOrderIds);
            orderCustomerGoodsDto.setOrderVendorIds(vendorOrderIds);
            orderCustomerGoodsDto.setBrand(brand);
            orderCustomerGoodsDto.setName(name);
            orderCustomerGoodsDto.setModel(model);
            orderCustomerGoodsDto.setSpec(spec);
            orderCustomerGoodsDto.setPageIndex(page);
            orderCustomerGoodsDto.setPageSize(limit);
            orderCustomerGoodsDto.setOrderGoodsStatusV1Enum(null == statusCode ? null : OrderGoodsStatusV1Enum.get(statusCode));
            BOList boList = orderCustomerBaseV1Service.listOrderCustomerGoodsContainMemberIds(orderCustomerGoodsDto);

            if (null == boList || 0 == boList.getTotal() || null == boList.getData()) {
                return GatewayResponse.success("查询成功");
            }
            log.info("查询的数据 result:{}", boList);

            count = boList.getTotal();
            //将 orderCustomerGoods boList 转换成 orderGoodsV1VOList
            orderGoodsV1VOList = orderCustomerBaseV1Service.transferOrderCustomerGoodsV1VOList(boList);
        } else if (sessionUser.isVendor()) {
            //查询 供应商订单商品
            OrderVendorGoodsDto orderVendorGoodsDto = new OrderVendorGoodsDto();
            orderVendorGoodsDto.setIds(orderGoodsIds);
            orderVendorGoodsDto.setOrderCustomerIds(customerOrderIds);
            orderVendorGoodsDto.setOrderVendorIds(vendorOrderIds);
            orderVendorGoodsDto.setBrand(brand);
            orderVendorGoodsDto.setName(name);
            orderVendorGoodsDto.setModel(model);
            orderVendorGoodsDto.setSpec(spec);
            orderVendorGoodsDto.setPageIndex(page);
            orderVendorGoodsDto.setPageSize(limit);
            orderVendorGoodsDto.setOrderGoodsStatusV1Enum(null == statusCode ? null : OrderGoodsStatusV1Enum.get(statusCode));

            BOList boList = orderVendorBaseV1Service.listOrderVendorGoodsContainMemberIds(orderVendorGoodsDto);

            if (null == boList || 0 == boList.getTotal() || null == boList.getData()) {
                return GatewayResponse.success("查询成功");
            }
            log.info("查询的数据 result:{}", boList);

            count = boList.getTotal();
            //将 orderVendorGoods boList 转换成 orderGoodsV1VOList
            orderGoodsV1VOList = orderVendorBaseV1Service.transferOrderVendorGoodsV1VOList(boList);

        }
        log.info("[customerGoodsPage] end  >>>>>>>");
        return GatewayResponse.success(count, "查询成功", orderGoodsV1VOList);
    }

    @Path("customerByPage")
    @POST
    @Operation(summary = "对外接口-分页查询客户订单(customerPage)", tags = CUSTOM_SERVICE, description = "分页查询客户订单")
    public GatewayResponse customerByPage(@Parameter GatewayParam param) {
        log.info("[customerByPage] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "get");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");

        UserDto currentUser = UserUtils.getCurrentUser();
        Assert.notNull(currentUser, "当前登录用户 不能为空");

        List<String> memberIds = UserUtils.listSubMemberIds(currentUser.getId());
        //订单id集合(逗号分隔)
        String newOrderIds = (String) body.get("newOrderIds");
        //收货地址
        String address = (String) body.get("address");
        //客户订单号
        String erpPO = (String) body.get("erpPO");
        //联系电话
        String phone = (String) body.get("phone");
        //收货人
        String receiver = (String) body.get("receiver");
        //客户订单号 1:新建 2:待付款 3:已付款 4:退货 5:取消 6:已完成 7:已驳回
        Integer statusCode = BigDecimalUtils.bigDecimalToInteger(body.get("statusCode"));
        //当前第几页（默认1）
        Integer page = BigDecimalUtils.bigDecimalToInteger(body.get("page"), 0);
        //每页条目数（limit<=100,默认20）
        Integer limit = BigDecimalUtils.bigDecimalToInteger(body.get("limit"), 20);
        //订单id集合
        List<String> orderIds = (List<String>) body.get("orderIds[]");

        if (org.apache.commons.lang3.StringUtils.isNotBlank(newOrderIds)) {
            if (CollectionUtils.isNotEmpty(orderIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderIds = StringUtils.commaDelimitedTrimEmptyListString(newOrderIds);
        }

        CustomerOrderService customerOrderService = new CustomerOrderService();
        OrderCustomerDto dto = new OrderCustomerDto();
        dto.setPlaceOrderUserIdList(memberIds);
        dto.setIds(orderIds);
        dto.setAddress(address);
        dto.setErpPO(erpPO);
        dto.setPhone(phone);
        dto.setReceiver(receiver);
        dto.setCustomerOrderStatusV1Enum(null == statusCode ? null : CustomerOrderStatusV1Enum.get(statusCode));
        dto.setPageIndex(page);
        dto.setPageSize(limit);

        BOList boList = orderCustomerBaseV1Service.listBoAllContainMemberIds(dto);
        if (null == boList || 0 == boList.getTotal() || null == boList.getData()) {
            return GatewayResponse.success("查询成功");
        }
        log.info("查询的数据 result:{}", boList);

        List<Map<String, Object>> customerOrderList = boList.getData();
        int total = boList.getTotal();

        List<CustomerOrderV1VO> customerOrderV1VOList = new ArrayList<>();
        for (Map<String, Object> orderCustomer : customerOrderList) {

            CustomerOrderV1VO customerOrderV1VO = CustomerOrderV1VO.of().setOrderId(String.valueOf(orderCustomer.get("id")))
                    .setClientOrderId(String.valueOf(orderCustomer.get("client_order_id")))
                    .setStatus(String.valueOf(orderCustomer.get("order_customer_status")))
                    .setErpPO(String.valueOf(orderCustomer.get("erp_po")))
                    .setReceiver(String.valueOf(orderCustomer.get("receiver")))
                    .setPhone(String.valueOf(orderCustomer.get("phone")))
                    .setPostal(String.valueOf(orderCustomer.get("postal")))
                    .setAddress(String.valueOf(orderCustomer.get("address")))
                    .setTotal(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("total")))
                    .setFreight(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("freight")))
                    .setPretaxAmount(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("pretax_amount")))
                    .setAmount(BigDecimalUtils.integerToBigDecimal(orderCustomer.get("amount")))
                    .setMemberName(String.valueOf(orderCustomer.get("place_order_fullname")))
                    .setTime(Utils.strToDate(String.valueOf(orderCustomer.get("createdTime"))))
                    .setApprovalBy(String.valueOf(orderCustomer.get("approval_by")))
                    .setApprovalOpinion(String.valueOf(orderCustomer.get("approval_opinion")))
                    .setCustomerName(String.valueOf(orderCustomer.get("organization_name")));

            //获取 对应的供应商订单
            List<Map<String, Object>> vendorOrderList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).selectField("*").eq("order_customer_id", orderCustomer.get("id")).queryForList();

            Assert.isTrue(CollectionUtils.isNotEmpty(vendorOrderList), "查询供应商订单信息 不能为空");

            //todo 需要判断当前用户是否是平台用户 权限过滤数据使用
            List<Map<String, Object>> vendorOrderGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).selectField("*").eq("order_customer_id", orderCustomer.get("id")).queryForList();

            Assert.isTrue(CollectionUtils.isNotEmpty(vendorOrderGoodsList), "查询供应商订单商品信息 不能为空");

            List<String> relationIdList = vendorOrderGoodsList.stream().map(e -> String.valueOf(e.get("relation_id"))).collect(Collectors.toList());

            List<Map<String, Object>> goodsRelationList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RELATION).selectField("*").in("id", relationIdList).queryForList();

            Map<String, Map<String, Object>> relationMap = null;
            if (!CollectionUtils.isEmpty(goodsRelationList)) {
                relationMap = goodsRelationList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

            }

            Map<String, Map<String, Object>> vendorOderMap = vendorOrderList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

            List<OrderGoodsV1VO> orderGoodsV1VOList = new LinkedList<>();
            for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {

                Map<String, Object> relation = null == relationMap ? null : relationMap.getOrDefault(String.valueOf(vendorOrderGoods.get("relation_id")), null);
                Map<String, Object> vendorOder = vendorOderMap.getOrDefault(String.valueOf(vendorOrderGoods.get("order_vendor_id")), null);

                int attachmentSize = 0;
                if (vendorOrderGoods.get("attachment") != null) {
                    List<AttachmentFormat> attachment = JsonParseObject.parseObject(String.valueOf(vendorOrderGoods.get("attachment")), AttachmentFormat.class);
                    attachmentSize = attachment.size();
                }

                Map<String, Object> inquiry = null;
                if (null != relation) {
                    //询价
                    String inquiryId = String.valueOf(relation.get("inquiry_id"));
                    inquiry = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY).selectField("*").eq("id", inquiryId).queryForMap();
                }

                //报价
                Map<String, Object> quotationGoods = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS).selectField("*").eq("id", vendorOrderGoods.get("goods_id")).queryForMap();

                OrderGoodsV1VO orderGoodsV1VO = OrderGoodsV1VO.of().setOrderGoodsId(String.valueOf(vendorOrderGoods.get("id")))
                        .setClientOrderGoodsId(String.valueOf(vendorOrderGoods.get("client_order_goods_id")))
                        .setCustomerOrderId(String.valueOf(vendorOrderGoods.get("order_customer_id")))
                        .setVendorOrderId(String.valueOf(vendorOrderGoods.get("order_vendor_id")))
                        .setVendorName(String.valueOf(vendorOrderGoods.get("vendor_organization_name")))
                        .setName(String.valueOf(vendorOrderGoods.get("name")))
                        .setBrand(String.valueOf(vendorOrderGoods.get("brand")))
                        .setModel(String.valueOf(vendorOrderGoods.get("model")))
                        .setSpec(String.valueOf(vendorOrderGoods.get("spec")))
                        .setSku(String.valueOf(vendorOrderGoods.get("sku")))
                        .setBarCode(String.valueOf(vendorOrderGoods.get("bar_code")))
                        .setUnspsc(String.valueOf(vendorOrderGoods.get("unspsc")))
                        .setGoldenTax(String.valueOf(vendorOrderGoods.get("golden_tax")))
                        .setImages(String.valueOf(vendorOrderGoods.get("images")))
                        .setDescription(String.valueOf(vendorOrderGoods.get("description")))
                        .setTechnical(String.valueOf(vendorOrderGoods.get("technical")))
                        .setPackaging(String.valueOf(vendorOrderGoods.get("packaging")))
                        .setMemo(String.valueOf(vendorOrderGoods.get("memo")))
                        .setUnit(String.valueOf(vendorOrderGoods.get("unit")))
                        .setPackageUnit(String.valueOf(vendorOrderGoods.get("package_unit")))
                        .setNum(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("quantity")))
                        .setPackageNum(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("package_quantity")))
                        .setDelivery(BigDecimalUtils.bigDecimalToInteger(vendorOrderGoods.get("delivery")))
                        .setTaxRate(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("tax_rate")))
                        .setTaxRateFreight(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("freight_rate")))
                        .setPretaxPrice(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_price")))
                        .setPrice(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("price")))
                        .setPretaxFreight(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_freight")))
                        .setFreight(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("freight")))
                        .setPretaxTotal(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_total")))
                        .setTotal(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("total")))
                        .setPretaxAmount(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("pretax_amount")))
                        .setAmount(BigDecimalUtils.integerToBigDecimal(vendorOrderGoods.get("amount")))
                        .setStatus(String.valueOf(vendorOrderGoods.get("order_vendor_goods_status")))
                        .setAttachment(String.valueOf(attachmentSize))
                        .setOrderType(String.valueOf(orderCustomer.get("type")))
                        .setCustomerOrgName(String.valueOf(vendorOrderGoods.get("customer_organization_name")))
                        .setMemberName(String.valueOf(orderCustomer.get("place_order_fullname"))) //实际下单人？
                        .setTime(Utils.strToDate(String.valueOf(vendorOder.get("createdTime"))))
                        .setClarifyTips(quotationGoods == null ? null : String.valueOf(quotationGoods.get("clarify_tips")))
                        .setCategory(String.valueOf(vendorOrderGoods.get("category")))
                        .setRemarkMessages(quotationGoods == null ? null : String.valueOf(quotationGoods.get("remark_message")))
                        .setQuotationGoodsId(String.valueOf(vendorOrderGoods.get("goods_id")))
                        .setDemandDeptName(inquiry == null ? null : String.valueOf(inquiry.get("department_name")))
                        .setInquiryMemberName(inquiry == null ? null : String.valueOf(inquiry.get("member_name")));

                orderGoodsV1VOList.add(orderGoodsV1VO);
            }

            customerOrderV1VOList.add(customerOrderV1VO);
        }

        log.info("[customerByPage] end  >>>>>>>");
        return GatewayResponse.success(total, "查询成功", customerOrderV1VOList);
    }

    @Path("orderSimpleCreate")
    @POST
    @Operation(summary = "对外接口-客户极简参数创建订单(saveSimple)", tags = CUSTOM_SERVICE, description = "客户极简参数创建订单")
    public GatewayResponse<OrderSimpleResult> orderSimpleCreate(@Parameter GatewayParam param) {
        log.info("[orderSimpleCreate] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");
        SessionUser sessionUser = new SessionUser();
        if (null == sessionUser.get()) throw new BizException("未获取到登录信息!");
        Assert.isTrue(sessionUser.isCustomer(), "只有客户角色才可创建订单!");

        //todo 待加锁  saveSimpleRepeatedSubmit

        String errorMessage = orderCustomerBaseV1Service.verifyOrderSimple(body);
        //验证失败直接返回
        if (errorMessage.length() > 0) {
            log.info("saveSimple-verify-fail-result:{},param:{}", errorMessage, param);
            return GatewayResponse.failed(errorMessage);
        }

        OrderSimple orderSimple = new OrderSimple();
        orderSimple.setClientUserId((String) body.get("clientUserId"));
        orderSimple.setClientOrderId((String) body.get("clientOrderId"));
        orderSimple.setErpPO((String) body.get("erpPO"));
        orderSimple.setReceiver((String) body.get("receiver"));
        orderSimple.setPhone(Objects.toString(body.get("phone")));
        orderSimple.setAddress((String) body.get("address"));
        orderSimple.setClientOs((String) body.get("clientOs"));
        orderSimple.setActualOrder((String) body.get("actualOrder"));
        orderSimple.setOrderGoodsList(JsonParseObject.parseObject(JSON.toJSONString(body.get("orderGoodsList")), OrderGoodsSimple.class));

        // 查询相关订单是否已经创建了
        if (StringUtils.isNotBlank(orderSimple.getClientOrderId())) {
            List<Map<String, Object>> maps = orderCustomerBaseV1Service.findAllByClientOrderId(orderSimple.getClientOrderId(), sessionUser.getCurrentClientID());

            if (!CollectionUtils.isEmpty(maps)) {

                List<OrderSimpleResult> orderResultList = new ArrayList<>();
                for (Map<String, Object> customerOrder : maps) {

                    List<OrderGoodsSimpleResult> orderGoodsResultList = new ArrayList<>();

                    List<Map<String, Object>> vendorOrderGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).selectField("*").in("order_customer_id", customerOrder.get("id")).queryForList();

                    for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {

                        orderGoodsResultList.add(OrderGoodsSimpleResult.builder().clientOrderGoodsId(String.valueOf(vendorOrderGoods.get("client_order_goods_id")))
                                .orderGoodsId(String.valueOf(vendorOrderGoods.get("id"))).build());
                    }

                    orderResultList.add(OrderSimpleResult.builder().clientOrderId(String.valueOf(customerOrder.get("client_order_id")))
                            .orderId(String.valueOf(customerOrder.get("id"))).orderGoodsResultList(orderGoodsResultList).build());
                }

                return GatewayResponse.success("订单提交成功", orderResultList.get(0));
            }
        }

        CustomerOrderVo customerOrderVo = orderCustomerBaseV1Service.adaptationSaveSimple(orderSimple, sessionUser);

        //iCreateOrder 逻辑中已经加了事务
        IOrderCustomerVO iOrderCustomerVO = orderService.iCreateOrder(customerOrderVo);

        //todo 数据同步 publishEvent

        //        applicationEventPublisher.publishEvent(new
        //                OrderRemoteSyncEvent(this, busProperties.getId(),
        //                "**", OrderRemoteSyncEventParam.builder().type(OrderSyncEventTypeEnum.OrderCreate).orderCustomerId(customerOrder.getId()).build()));

        //todo 触发完成请购单 晶科 目前确定是不用做了
        //orderCustomerBaseV1Service.completePurchaseRequest(orderCustomer);

        log.info("[orderSimpleCreate] end  >>>>>>>");
        //buildOrderSimpleSuccessResult
        return GatewayResponse.success("订单提交成功", orderCustomerBaseV1Service.buildOrderSimpleSuccessResult(iOrderCustomerVO));
    }


    // @RequestBody
    @Path("orderCustomerPayment")
    @POST
    @Operation(summary = "对外接口-【客户】订单付款(payment)", tags = CUSTOM_SERVICE, description = "【客户】订单付款")
    public GatewayResponse orderCustomerPayment(@Parameter GatewayParam2 param) {
        log.info("[orderCustomerPayment] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Assert.notNull(param.getBody(), "请求参数查询条件 不能为空");
        SessionUser sessionUser = new SessionUser();
        if (null == sessionUser.get()) throw new BizException("未获取到登录信息!");

        List<Map<String, Object>> OrderV1PaymentList = param.getBody();

        Assert.isTrue(CollectionUtils.isNotEmpty(OrderV1PaymentList), "参数不能为空 ！！！");

        List<String> orderCustomerIdList = new ArrayList<>();
        List<String> erpPoList = new ArrayList<>();
        for (Map<String, Object> map : OrderV1PaymentList) {
            if (map.get("orderCustomerId") != null) {
                orderCustomerIdList.add(String.valueOf(map.get("orderCustomerId")));
            }

            if (map.get("erpPo") != null) {
                erpPoList.add(String.valueOf(map.get("erpPo")));
            }
        }

        if (CollectionUtils.isEmpty(orderCustomerIdList) && CollectionUtils.isEmpty(erpPoList)) {

            return GatewayResponse.failed("参数 erpPo和订单ID必须传一个 ");
        }

        List<Map<String, Object>> orderCustomerList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderCustomerIdList) & !CollectionUtils.isEmpty(erpPoList)) {
            orderCustomerList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").in("id", orderCustomerIdList)
                    .in("erp_po", erpPoList).eq(" organization_id -> '$.id' ", sessionUser.getCurrentOrgID()).queryForList();
        } else if (!CollectionUtils.isEmpty(orderCustomerIdList)) {
            orderCustomerList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").in("id", orderCustomerIdList)
                    .eq(" organization_id -> '$.id' ", sessionUser.getCurrentOrgID()).queryForList();
        } else if (!CollectionUtils.isEmpty(erpPoList)) {
            orderCustomerList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").in("erp_po", erpPoList)
                    .eq(" organization_id -> '$.id' ", sessionUser.getCurrentOrgID()).queryForList();
        }

        if (CollectionUtils.isEmpty(orderCustomerList)) {

            return GatewayResponse.failed("未获取到要付款的订单，请检查参数是否正确");
        }

        List<String> customerOrderIds = new ArrayList<>();
        List<Map<String, Object>> filterOrderCustomerList = new ArrayList<>();
        for (Map<String, Object> orderCustomer : orderCustomerList) {
            //注意这里新老状态的转换
            if (OrderCustomerStatusEnum.UpcomingPayment.name().equals(orderCustomer.get("order_customer_status")) && orderCustomer.get("label") != null
                    && orderCustomer.get("label").toString().contains(OrderApproveStatusEnum.APPROVING.id.toString())) {
                // 新建 ==》未付款 & label：审批中
                // label
                return GatewayResponse.failed("付款失败", "订单编号【" + orderCustomer.get("id") + "】处于审批状态");
            }

            if (OrderCustomerStatusEnum.UpcomingPayment.name().equals(orderCustomer.get("order_customer_status")) && orderCustomer.get("label") != null
                    && orderCustomer.get("label").toString().contains(OrderApproveStatusEnum.APPROVAL_REJECTION.id.toString())) {
                //已驳回 =》未付款 & label：审批驳回
                // label
                return GatewayResponse.failed("付款失败", "订单编号【" + orderCustomer.get("id") + "】处于审批状态");
            }

            if (OrderCustomerStatusEnum.Closed.name().equals(orderCustomer.get("order_customer_status"))) {
                // 取消 =》已关闭
                return GatewayResponse.failed("付款失败", "订单编号【" + orderCustomer.get("id") + "】已取消");
            }

            //待付款 =》未付款 & label!=审批中
            // label
            if (OrderCustomerStatusEnum.UpcomingPayment.name().equals(orderCustomer.get("order_customer_status")) && (orderCustomer.get("label") == null
                    || !orderCustomer.get("label").toString().contains(OrderApproveStatusEnum.APPROVING.id.toString()))) {
                customerOrderIds.add(String.valueOf(orderCustomer.get("id")));
                filterOrderCustomerList.add(orderCustomer);
            }
        }

        if (CollectionUtils.isEmpty(customerOrderIds)) {
            return GatewayResponse.success(202, "付款成功", null);
        }

        OrderCustomerDto orderCustomerDto = new OrderCustomerDto();
        orderCustomerDto.setOrderCustomerStatus(OrderCustomerStatusEnum.UpcomingConfirm);
        orderCustomerDto.setIds(customerOrderIds);
        orderService.batchUpdateOrderCustomer(orderCustomerDto);

        //todo 数据同步 publishEvent
//        applicationEventPublisher.publishEvent(new
//                OrderRemoteSyncEvent(this, busProperties.getId(),
//                "**", OrderRemoteSyncEventParam.builder()
//                .type(OrderSyncEventTypeEnum.OrderPayment).orderCustomerIds(customerOrderIds).build()));

        log.info("[orderCustomerPayment] end  >>>>>>>");
        return GatewayResponse.success("付款成功");
    }

    @Path("orderCustomerReceive")
    @POST
    @Operation(summary = "对外接口-【客户】收货(customerReceive)", tags = CUSTOM_SERVICE, description = "【客户】收货")
    public GatewayResponse orderCustomerReceive(@Parameter GatewayParam param) {
        log.info("[orderCustomerReceive] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getBody(), "请求参数查询条件 不能为空");

        //订单商品id集合(逗号分隔)
        String newOrderGoodsIds = (String) body.get("newOrderGoodsIds");

        List<String> orderGoodsIds = (List<String>) body.get("orderGoodsIds[]");

        if (org.apache.commons.lang3.StringUtils.isNotBlank(newOrderGoodsIds)) {
            if (CollectionUtils.isNotEmpty(orderGoodsIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderGoodsIds = StringUtils.commaDelimitedTrimEmptyListString(newOrderGoodsIds);
        } else {
            log.warn("使用过期参数 [orderCustomerReceive]-orderGoodsIds[] , {}", org.apache.commons.lang3.StringUtils.join(orderGoodsIds, ","));
        }

        if (orderGoodsIds == null || orderGoodsIds.isEmpty()) {
            return GatewayResponse.failed("参数不能为空! ");
        }
        String requestId = UUID.randomUUID().toString();

        try {
            // 加锁
            Boolean aBoolean = RedisLockUtil.lock(EncryptUtils.MD5_32(ZookeeperLockConstants.CUSTOMER_RECEIVE_V1 + orderGoodsIds), 300, 30, requestId);
            Assert.isTrue(aBoolean, "请勿重复提交! ");

            // 已完成 =》已完成
            //@Query(value = "SELECT id FROM OrderGoodsEntity where id in ?1 and del = false and status = ?2")
            //List<Integer> getOrderGoods(List<Integer> orderGoodsIds, OrderGoodsStatusEnum orderGoodsStatus);

            List<Map<String, Object>> customerGoodsIdsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS).selectField("id").in("id", orderGoodsIds).eq("order_customer_goods_status", OrderGoodsStatusEnum.Done).queryForList();

            if (CollectionUtils.isNotEmpty(customerGoodsIdsList)) {
                List<String> ids = customerGoodsIdsList.stream().map(e -> String.valueOf(e.get("id"))).collect(Collectors.toList());
                if (customerGoodsIdsList.size() == orderGoodsIds.size()) {
                    return GatewayResponse.success(ids.size(), "该商品已收货", ids);
                }

                orderGoodsIds = orderGoodsIds.stream().filter(e -> !ids.contains(e)).collect(Collectors.toList());
            }

            //iOrderBiz.customerGoodsReceive(orderGoodsIds);
            List<Map<String, Object>> customerGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS).selectField("*").in("id", orderGoodsIds).queryForList();
            for (Map<String, Object> customerGoods : customerGoodsList) {
                //  待收货 =》已发货
                if (!OrderGoodsStatusEnum.DoneDelivery.name().equals(customerGoods.get("order_customer_goods_status"))) {
                    return GatewayResponse.failed("收货失败：商品【" + customerGoods.get("id") + "】不是已发货状态！");
                }
            }

            List<String> successIds = new ArrayList<>();
            for (String orderGoodsId : orderGoodsIds) {

                BigDecimal enableNum = orderCustomerBaseV1Service.getOrderGoodsEnableNum(orderGoodsId);
                Boolean execute = transactionTemplate.execute(flag -> orderService.goodsReceipt(orderGoodsId, enableNum));
                if(execute) successIds.add(orderGoodsId);
            }

            //事务
//            TempOrderReceiptVo tempOrderReceiptVo = transactionTemplate.execute(tempOrderReceiptVoStatus -> orderService.goodsReceiptBatch(orderGoodsIdsTemp));
            //需要修改一下返回参数
            //TempOrderReceiptVo tempOrderReceiptVo = orderService.goodsReceiptBatch(orderGoodsIds);

            //todo 数据同步 publishEvent
            if (!CollectionUtils.isEmpty(successIds)) {
//            applicationEventPublisher.publishEvent(new
//                    OrderRemoteSyncEvent(this, busProperties.getId(),
//                    "**", OrderRemoteSyncEventParam.builder()
//                    .type(OrderSyncEventTypeEnum.GoodsReceipt).orderGoodsAcceptIds(data.getReceivedIds()).build()));
            }


            int count = 0;
            if (CollectionUtils.isNotEmpty(successIds))
                count = successIds.size();
            //todo 返回数据结果待封装
            log.info("[orderCustomerReceive] end  >>>>>>>");
            return GatewayResponse.success(count, "收货成功", successIds);
        } finally {
            Boolean aBoolean = RedisLockUtil.unlock(EncryptUtils.MD5_32(ZookeeperLockConstants.CUSTOMER_RECEIVE_V1 + orderGoodsIds), requestId);
            if (!aBoolean) {
                log.warn("【orderCustomerReceive】 解锁失败 key：{}", ZookeeperLockConstants.CUSTOMER_RECEIVE_V1 + orderGoodsIds);
            }
        }
    }

    @Path("orderCustomerReceiveByErpPoAndSku")
    @POST
    @Operation(summary = "对外接口-根据erpPo和sku、number收货(customerReceiveByErpPoAndSku)", tags = CUSTOM_SERVICE, description = "根据erpPo和sku、number收货")
    public GatewayResponse orderCustomerReceiveByErpPoAndSku(@Parameter GatewayParam param) {
        log.info("[orderCustomerReceiveByErpPoAndSku] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getBody(), "请求参数查询条件 不能为空");

        Assert.isTrue(StringUtils.isNotBlank(String.valueOf(body.get("item"))), " 收货明细不能为空");

        List<ReceiveItemVo> receiveItemVoList = JsonParseObject.parseObject(JSON.toJSONString(body.get("item")), ReceiveItemVo.class);

        List<String> orderGoodsIds = new ArrayList<>();

        List<String> returnMsg = new ArrayList<>();
        boolean verify = true;
        for (ReceiveItemVo receiveItemVo : receiveItemVoList) {
            String erpPo = receiveItemVo.getErpPo();
            BigDecimal num = receiveItemVo.getNum();
            String sku = receiveItemVo.getSku();

            if (erpPo == null || erpPo.isEmpty()) {
                returnMsg.add("商品信息:" + erpPo + sku + ":erpPo不能为空!");
                verify = false;
                break;
            }

            if (sku == null || sku.isEmpty()) {

                StringBuilder st = new StringBuilder(" SELECT g.* FROM ");
                st.append(ModelConst.T_ORDER_CUSTOMER_GOODS);
                st.append(" g LEFT JOIN  ");
                st.append(ModelConst.T_ORDER_CUSTOMER);
                st.append(" c  ON  c.id = g.order_customer_id  ");
                st.append(" WHERE g.del = FALSE AND c.del = FALSE AND c.erp_po = :erp_po  ");
                Map<String, Object> queryParam = new HashMap<>();
                queryParam.put("erp_po", erpPo);
                List<Map<String, Object>> goodsList = JdbcTemplateUtils.queryForList(st.toString(), queryParam);

                if (CollectionUtils.isEmpty(goodsList) || goodsList.size() > 1) {

                    returnMsg.add("商品信息:" + erpPo + sku + ":sku不唯一或者sku为空!");
                    verify = false;
                    break;
                }
                sku = String.valueOf(goodsList.get(0).get("sku"));
            }
            if (num == null || num.compareTo(BigDecimal.ZERO) == 0) {
                returnMsg.add("商品信息:" + erpPo + sku + ":num不能为空!");
                verify = false;
                break;
            }
            // 通过erpPo 和 sku查询具体的订单商品
            StringBuilder sql = new StringBuilder(" SELECT g.* FROM ");
            sql.append(JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS));
            sql.append(" g LEFT JOIN  ");
            sql.append(JdbcTemplateUtils.getTableName(ModelConst.T_ORDER_CUSTOMER));
            sql.append(" c  ON  c.id = g.order_customer_id  ");
            sql.append(" WHERE g.deleted = FALSE AND c.deleted = FALSE AND c.erp_po = :erp_po  AND g.sku = :sku");
            Map<String, Object> queryParam = new HashMap<>();
            queryParam.put("erp_po", erpPo);
            queryParam.put("sku", sku);

            log.info("sql:{},param:{}", sql, queryParam);
            List<Map<String, Object>> customerGoodsList = JdbcTemplateUtils.queryForList(sql.toString(), queryParam);

            if (CollectionUtils.isEmpty(customerGoodsList)) {
                returnMsg.add("未查询到erp Po:" + erpPo + ",sku:" + sku + "!!!");
                verify = false;
                break;
            }
            // 验证商品id集 状态是否满足收货
            if (String.valueOf(customerGoodsList.get(0).get("order_customer_goods_status")).equals(OrderGoodsStatusEnum.Done.name())) {
                returnMsg.add("该商品已收货、sku:" + sku + "、erp Po:" + erpPo);
                verify = false;
                break;
            }

            orderGoodsIds.add(String.valueOf(customerGoodsList.get(0).get("id")));
        }

        if (!verify) {
            log.warn("orderV1Controller->customerReceiveByErpPoAndSku:收货失败，失败信息：" + returnMsg, orderGoodsIds.size(), orderGoodsIds);
            return GatewayResponse.failed("收货失败，失败信息：" + returnMsg);
        }

//        List<String> orderGoodsIdsTemp = orderGoodsIds;

        List<String> successIds = new ArrayList<>();
        for (String orderGoodsId : orderGoodsIds) {

            BigDecimal enableNum = orderCustomerBaseV1Service.getOrderGoodsEnableNum(orderGoodsId);
            Boolean execute = transactionTemplate.execute(flag -> orderService.goodsReceipt(orderGoodsId, enableNum));
            if(execute) successIds.add(orderGoodsId);
        }
//        TempOrderReceiptVo tempOrderReceiptVo = transactionTemplate.execute(tempOrderReceiptVoStatus -> orderService.goodsReceiptBatch(orderGoodsIdsTemp));

        //TempOrderReceiptVo tempOrderReceiptVo = orderService.goodsReceiptBatch(orderGoodsIds);

        //todo 数据同步 publishEvent
        if (CollectionUtils.isNotEmpty(successIds)) {
//            applicationEventPublisher.publishEvent(new
//                    OrderRemoteSyncEvent(this, busProperties.getId(),
//                    "**", OrderRemoteSyncEventParam.builder()
//                    .type(OrderSyncEventTypeEnum.GoodsReceipt).orderGoodsAcceptIds(result.getReceivedIds()).build()));
        }

        log.info("[orderCustomerReceiveByErpPoAndSku] end  >>>>>>>");
        return GatewayResponse.success("收货成功");
    }

    @Path("orderCustomerCompleteReceive")
    @POST
    @Operation(summary = "对外接口-整单收货(completeReceive)", tags = CUSTOM_SERVICE, description = "整单收货")
    public GatewayResponse orderCustomerCompleteReceive(@Parameter GatewayParam param) {
        log.info("[orderCustomerCompleteReceive] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getBody(), "请求参数查询条件 不能为空");
        SessionUser sessionUser = new SessionUser();
        if (null == sessionUser.get()) throw new BizException("未获取到登录信息!");
        //订单商品id集合(逗号分隔)
        String orderCustomerIds = (String) body.get("orderCustomerIds");

        if (StringUtils.isBlank(orderCustomerIds) || !RegexUtils.check(RegexUtils.Type.ONLY_NUMBER_OR_EMPTY, orderCustomerIds)) {
            return GatewayResponse.failed("参数不可为空或格式错误");
        }

        List<String> orderCustomerIdList = new ArrayList<>();
        for (String orderCustomerId : org.apache.commons.lang3.StringUtils.split(orderCustomerIds, ",")) {
            orderCustomerIdList.add(String.valueOf(orderCustomerId));
        }

        List<String> memberIds = UserUtils.listSubMemberIds(sessionUser.getCurrentUserId());
//        Assert.isTrue(CollectionUtils.isNotEmpty(memberIds), "获取下属员工 id 列表 不能为空");
        List<Map<String, Object>> orderCustomerGoodsList = null;
        //客户订单id
        if (CollectionUtils.isEmpty(memberIds)) {
            //如果返回为空，就表示当前用户 具有所有数据查看权限 直接根据id查询出来数据
            orderCustomerGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS).
                    selectField("*").in("order_customer_id", orderCustomerIdList).queryForList();
        } else {
            //有数据需要过滤
            orderCustomerGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS).selectField("*").in("order_customer_id", orderCustomerIdList)
                    .in("JSON_UNQUOTE(place_order_user_id ->'$.id')", memberIds).queryForList();
        }

        if (CollectionUtils.isEmpty(orderCustomerGoodsList)) {
            return GatewayResponse.failed("未查到要收货的商品，请检查订单ID是否正确");
        }
        List<String> orderGoodsIds = new ArrayList<>();
        //校验数据
        for (Map<String, Object> orderCustomerGoods : orderCustomerGoodsList) {

            //select count(refund) from OrderGoodsRefundEntity refund where refund.del=false and refund.orderGoodsId in (?1) and refund.status <>5 and refund.status<>7
            //t_order_goods_returns
            List<Map<String, Object>> mapList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RETURNS).selectField("*").eq("order_customer_goods_id", orderCustomerGoods.get("id"))
                    .notEq("order_goods_returns_status", OrderGoodsReturnsStatusEnum.Done).queryForList();

            Assert.isTrue(CollectionUtils.isEmpty(mapList), "订单存在退款进行中的商品，需要退款结束才可收货");

            //已发数量

            List<Map<String, Object>> orderTraceList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_TRACE).selectField("*").eq("order_customer_goods_id", orderCustomerGoods.get("id")).eq("type", TraceTypeEnum.ShippingLogistics.name()).queryForList();

            BigDecimal deliveredNum = BigDecimal.ZERO;
            if (!CollectionUtils.isEmpty(orderTraceList)) {
                for (Map<String, Object> orderTrace : orderTraceList) {
                    if (null == orderTrace.get("quantity")) {
                        continue;
                    }
                    BigDecimal quantity = BigDecimalUtils.integerToBigDecimal(orderTrace.get("quantity"));
                    deliveredNum = quantity.add(deliveredNum);
                }
            }

            //已收数量

            List<Map<String, Object>> orderGoodsAcceptList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_ACCEPT).selectField("*").eq("order_customer_goods_id", orderCustomerGoods.get("id")).queryForList();

            BigDecimal receivedNum = BigDecimal.ZERO;
            if (!CollectionUtils.isEmpty(orderGoodsAcceptList)) {
                for (Map<String, Object> orderGoodsAccept : orderGoodsAcceptList) {
                    if (null == orderGoodsAccept.get("quantity")) {
                        continue;
                    }
                    BigDecimal quantity = BigDecimalUtils.integerToBigDecimal(orderGoodsAccept.get("quantity"));
                    receivedNum = quantity.add(receivedNum);
                }
            }

            BigDecimal returnReceivedNum = BigDecimalUtils.integerToBigDecimal(orderCustomerGoods.get("return_received_num"));
            BigDecimal returnedNum = BigDecimalUtils.integerToBigDecimal(orderCustomerGoods.get("returned_num"));
            BigDecimal quantity = BigDecimalUtils.integerToBigDecimal(orderCustomerGoods.get("quantity"));
            //可收数量（已发数量-已收数量-已退货数量+退的收货的数量）
            BigDecimal enableNum = deliveredNum.subtract(receivedNum).subtract(returnedNum).add(returnReceivedNum);

            String errorMessage = "订单商品编号【" + orderCustomerGoods.get("id") + "】可收货数量【" + enableNum + "】必须";
            //如果可收货数量数量不等于订单总数量，需要判断是否存在已退数量
            if (enableNum.compareTo(quantity) != 0) {
                List<Map<String, Object>> orderGoodsRefundList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RETURNS).
                        selectField("*").eq("order_customer_goods_id", orderCustomerGoods.get("id")).queryForList();
                BigDecimal refundQuantity = BigDecimal.ZERO;
                if (CollectionUtils.isNotEmpty(orderGoodsRefundList)) {
                    for (Map<String, Object> orderGoodsRefund : orderGoodsRefundList) {
                        if (String.valueOf(orderGoodsRefund.get("order_goods_returns_status")).equals(OrderGoodsReturnsStatusEnum.Done)) {
                            BigDecimal num = BigDecimalUtils.integerToBigDecimal(orderGoodsRefund.get("quantity"));
                            refundQuantity = refundQuantity.add(num);
                        }
                    }
                }
                //Double refundQuantity = this.verifyCompleteReceiveRefund(orderGoods.getId());
                BigDecimal subRefundGoodsQuantity = quantity.subtract(refundQuantity);
                //如果全退完，不可以影响收货，所以需要跳过
                if (subRefundGoodsQuantity.compareTo(BigDecimal.ZERO) == 0) {
                    continue;
                }

                if (enableNum.compareTo(subRefundGoodsQuantity) != 0) {
                    //兼容特殊情况在pm端部分收货
                    subRefundGoodsQuantity = subRefundGoodsQuantity.subtract(receivedNum);
                    Assert.isTrue(enableNum.compareTo(subRefundGoodsQuantity) == 0, errorMessage + "等于下单数量-已退数量【" + subRefundGoodsQuantity + "】");
                }
            }

            Assert.isTrue(enableNum.compareTo(BigDecimal.ZERO) > 0, errorMessage + "大于0");
            orderGoodsIds.add(String.valueOf(orderCustomerGoods.get("id")));
        }

        List<String> orderGoodsIdsTemp = orderGoodsIds;
        TempOrderReceiptVo tempOrderReceiptVo = transactionTemplate.execute(tempOrderReceiptVoStatus -> orderService.goodsReceiptBatch(orderGoodsIdsTemp));

        // TempOrderReceiptVo tempOrderReceiptVo = orderService.goodsReceiptBatch(orderGoodsIds);

        //todo 数据同步 publishEvent
        if (!CollectionUtils.isEmpty(tempOrderReceiptVo.getReceivedIds())) {
//            applicationEventPublisher.publishEvent(new
//                    OrderRemoteSyncEvent(this, busProperties.getId(),
//                    "**", OrderRemoteSyncEventParam.builder()
//                    .type(OrderSyncEventTypeEnum.GoodsReceipt).orderGoodsAcceptIds(receipt.getReceivedIds()).build()));
        }

        log.info("[orderCustomerCompleteReceive] end  >>>>>>>");
        return GatewayResponse.success("收货成功", "收货成功");
    }

    @Path("orderCustomerReturnGoods")
    @POST
    @Operation(summary = "对外接口-【客户】退货(returnGoods)", tags = CUSTOM_SERVICE, description = "【客户】退货")
    public GatewayResponse orderCustomerReturnGoods(@Parameter GatewayParam param) {
        log.info("[orderCustomerReturnGoods] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
//        Assert.notNull(param.getBody(), "请求参数查询条件 不能为空");

        //订单商品id集合(逗号分隔)
        String newOrderGoodsIds = (String) body.get("newOrderGoodsIds");

        List<String> orderGoodsIds = (List<String>) body.get("orderGoodsIds[]");

        if (org.apache.commons.lang3.StringUtils.isNotBlank(newOrderGoodsIds)) {
            if (CollectionUtils.isNotEmpty(orderGoodsIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderGoodsIds = StringUtils.commaDelimitedTrimEmptyListString(newOrderGoodsIds);
        } else {
            log.warn("使用过期参数 [goods-delivery]-orderGoodsIds[] , {}", org.apache.commons.lang3.StringUtils.join(orderGoodsIds, ","));
        }

        if (CollectionUtils.isEmpty(orderGoodsIds)) {
            return GatewayResponse.failed("参数不正确");
        }

        //物流单号
        String waybill = (String) body.get("waybill");
        //物流名称
        String logistics = (String) body.get("logistics");

        //事务
        //变更返回数据
        List<String> orderGoodsIdsTemp = orderGoodsIds;
        Map<String, List<String>> execute = transactionTemplate.execute(result -> orderService.goodsReturn(orderGoodsIdsTemp, logistics, waybill));

        //todo 数据同步 publishEvent


        log.info("[orderCustomerReturnGoods] end  >>>>>>>");
        return GatewayResponse.success(orderGoodsIds.size(), "退货成功！", orderGoodsIds);
    }

    @Path("orderCustomerApplyRefund")
    @POST
    @Operation(summary = "对外接口-【客户】申请退款(applyRefund)", tags = CUSTOM_SERVICE, description = "【客户】申请退款")
    public GatewayResponse orderCustomerApplyRefund(@Parameter GatewayParam2 param2) {

        log.info("[orderCustomerApplyRefund] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        //Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");
        Assert.notNull(param2.getBody(), "请求参数查询条件 不能为空");

        List<ApplyRefundVo> applyRefundVoList = JsonParseObject.parseObject(JSON.toJSONString(param2.getBody()), ApplyRefundVo.class);

        if (CollectionUtils.isEmpty(applyRefundVoList)) {
            return GatewayResponse.failed("退款申请信息不能为空！");
        }
        //todo 加事务
        List<BulkRefundVO> bulkRefundVOList = new ArrayList<>();
        for (ApplyRefundVo applyRefundVo : applyRefundVoList) {
            String requestId = UUID.randomUUID().toString();
            String orderGoodsId = applyRefundVo.getOrderGoodsId();

            try {
                // 加锁
                Boolean aBoolean = RedisLockUtil.lock(EncryptUtils.MD5_32(ZookeeperLockConstants.APPLY_REFUND_V1 + orderGoodsId), 300, 30, requestId);
                Assert.isTrue(aBoolean, "请勿重复操作! 商品ID: " + orderGoodsId);
                //获取退货订单数量
                Boolean orderGoods = orderCustomerBaseV1Service.getOrderGoods(orderGoodsId, "");
                if (orderGoods) continue;
                List<Map<String, Object>> execute = transactionTemplate.execute(result -> orderCustomerBaseV1Service.applyRefund(applyRefundVo));
            } finally {
                Boolean aBoolean = RedisLockUtil.unlock(EncryptUtils.MD5_32(ZookeeperLockConstants.APPLY_REFUND_V1 + orderGoodsId), requestId);
                if (!aBoolean) {
                    log.warn("【orderCustomerApplyRefund】 解锁失败 key：{}", ZookeeperLockConstants.APPLY_REFUND_V1 + orderGoodsId);
                }
            }
        }

        List<String> ids = applyRefundVoList.stream().map(ApplyRefundVo::getOrderGoodsId).collect(Collectors.toList());
        log.info("[orderCustomerApplyRefund] end  >>>>>>>");
        return GatewayResponse.success(ids.size(), "退款申请成功！", ids);
    }


    @Path("updateOrderCustomerErpPo")
    @POST
    @Operation(summary = "对外接口-批量修改ERP-PO(updateErpPo)", tags = CUSTOM_SERVICE, description = "批量修改ERP-PO")
    public GatewayResponse updateOrderCustomerErpPo(@Parameter GatewayParam2 param2) {

        log.info("[updateOrderCustomerErpPo] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Assert.notNull(param2.getBody(), "请求参数查询条件 不能为空");
        SessionUser sessionUser = new SessionUser();
        if (null == sessionUser.get()) throw new BizException("未获取到登录信息!");

        //updateErpPoVos
        List<Map<String, Object>> queryList = param2.getBody();

        Assert.isTrue(CollectionUtils.isNotEmpty(queryList), "参数不能为空 ！！！");


        Map<String, String> map = queryList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("orderId")), y -> String.valueOf(y.get("erpPo")), (oldValue, newValue) -> newValue));

        //    @Query("select c from CustomerOrderEntity c where c.id in(:orderIds) and c.clientId=:clientId and c.del = false")
        List<Map<String, Object>> customerOrderList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("*").
                in("id", map.keySet()).eq("place_order_user_id ->'$.id'", sessionUser.getCurrentUserId()).queryForList();

        Assert.isTrue(CollectionUtils.isNotEmpty(customerOrderList), "未获取到订单信息 ！！！");

        //修改成功的id
        List<String> successIds = new ArrayList<>();

        List<Map<String, Object>> needUpdateOrderList = new ArrayList<>();

        List<TradeErpPoUpdate> tradeErpPoUpdateList = new ArrayList<>();

        for (Map<String, Object> customerOrder : customerOrderList) {

            Assert.isTrue(null == customerOrder.get("erp_po") || StringUtils.isBlank((String) customerOrder.get("erp_po")), "原订单Erp-PO已存在！");

            String newErpPO = map.get(String.valueOf(customerOrder.get("id")));

            Assert.isTrue(StringUtils.isNotBlank(newErpPO), "新Erp-PO不能为空！");

            customerOrder.put("erp_po", newErpPO);
            successIds.add(String.valueOf(customerOrder.get("id")));
            tradeErpPoUpdateList.add(TradeErpPoUpdate.builder().customerOrderId(String.valueOf(customerOrder.get("id"))).erpPo(newErpPO).build());
            needUpdateOrderList.add(customerOrder);
        }

        List<String> updateResult = new ArrayList<>();
        for (Map<String, Object> needUpdateOrder : needUpdateOrderList) {
            String customerOrderId = String.valueOf(needUpdateOrder.get("id"));
            String erpPo = String.valueOf(needUpdateOrder.get("erp_po"));

            int update = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).putFieldAndVal("erp_po", erpPo).
                    eq("id", customerOrderId).update();

            Assert.isTrue(update > 0, "修改ERP-PO 失败！！！");
            // 需要同步 供应商订单，客户订单，供应商订单商品，客户订单商品
            JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).putFieldAndVal("erp_po", erpPo)
                    .eq("order_customer_id", customerOrderId).update();
            JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).putFieldAndVal("erp_po", erpPo)
                    .eq("order_customer_id", customerOrderId).update();
            JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS).putFieldAndVal("erp_po", erpPo)
                    .eq("order_customer_id", customerOrderId).update();

            updateResult.add(String.valueOf(needUpdateOrder.get("id")));
        }

        if (!CollectionUtils.isEmpty(updateResult)) {
            //todo 数据同步 publishEvent
//            applicationEventPublisher.publishEvent(new
//                    OrderRemoteSyncEvent(this, busProperties.getId(),
//                    "**", OrderRemoteSyncEventParam.builder()
//                    .type(OrderSyncEventTypeEnum.UpdateErpPo).orderCustomerIds(entityList.stream().map(BaseEntity::getId).collect(Collectors.toList())).build()));

        }

        if (!CollectionUtils.isEmpty(tradeErpPoUpdateList)) {
            log.info("更新 交易 ERP_PO开始");
            dockFinanceService.writeBackErpPo(tradeErpPoUpdateList);
            log.info("更新 交易 ERP_PO结束");
        }

        log.info("[updateOrderCustomerErpPo] end  >>>>>>>");
        return GatewayResponse.success(successIds.size(), "修改成功", successIds);
    }

    /**
     * 根据外部订单ID和商品ID进行收货
     * 固买url地址：v1/order/items/confirm-by-client-order-goods
     * 入参示例：{
     * "clientOrderId":"0000001",
     * "itemList":[{
     * "goodsId":"123"
     * }]
     * }
     */
    @Path("confirmByClientOrderGoods")
    @POST
    @Operation(summary = "根据外部订单ID和商品ID进行收货", tags = CUSTOM_SERVICE, description = "根据外部订单ID和商品ID进行收货")
    public GatewayResponse confirmByClientOrderGoods(@Parameter GatewayParam param) {
        Map<String, Object> body = null;
        GatewayResponse checkResponse = Utils.isNotNullGatewayParam(param, "post", "clientOrderId", "itemList");
        if (checkResponse.isSuccess()) {
            body = (Map) checkResponse.getData();
        } else {
            return checkResponse;
        }
        String clientOrderId = (String) body.get("clientOrderId");//外部订单ID 不能为空
        List<Map<String, Object>> itemList = (ArrayList) body.get("itemList");//收货明细 不能为空
        if (StringUtils.isBlank(clientOrderId) || CollectionUtils.isEmpty(itemList)) {
            return GatewayResponse.failed("外部订单ID和收货明细不能为空");
        }
        List<String> goodsIds = itemList.stream().map(t -> (String) t.get("goodsId")).collect(Collectors.toList());
        //根据外部订单ID和商品ID查询存在的订单商品ID
        String ocTableName = getTableName(ModelConst.T_ORDER_CUSTOMER);
        String ocgTableName = getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
        String sql = "select ocg.goods_id from " + ocgTableName + " ocg " +
                "LEFT JOIN " + ocTableName + " oc on oc.id = ocg.order_customer_id " +
                "where oc.client_order_id =:clientOrderId and ocg.goods_id in (:goodsIds)";
        Map<String, Object> goodsIdParam = new HashMap<>();
        goodsIdParam.put("clientOrderId", clientOrderId);
        goodsIdParam.put("goodsIds", goodsIds);
        List<Map<String, Object>> orderGoods = JdbcTemplateUtils.queryForList(sql, goodsIdParam);
        if (orderGoods.size() != goodsIds.size()) {
            log.warn("获取到的订单商品跟要收货的条目不一致，订单商品条数{}---商品条数{}", orderGoods.size(), goodsIds.size());
            return GatewayResponse.failed("获取到的订单商品跟要收货的条目不一致，请检查参数是否正确");
        }
        List<String> orderGoodIds = orderGoods.stream().map(t -> (String) t.get("goods_id")).collect(Collectors.toList());
        orderService.goodsReceiptBatch(orderGoodIds);
        return GatewayResponse.success("收货成功");
    }


}
